home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_187
/
diskperf
/
diskperf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
19KB
|
569 lines
/*
** Disk performance benchmark. If your Amiga configuration is substantially
** different from the ones mentioned here, please run the benchmark and
** report the results to either: ..!philabs!sbcs!rick or posting to
** comp.sys.amiga. Thanks!
**
** To compile benchmark for Unix 4.2/4.3 SUN 3.0/3.2:
**
** cc -o diskperf -O -DUNIX diskperf.c
**
** Amiga version was cross compiled from a SUN, so you'll have to figure out
** how to compile diskperf under your favorite compiler system. A uuencoded
** Amiga binary version of diskperfa is included with the shar file that
** contained this source listing.
**
** To run diskperf, simply type:
**
** diskperf [location], e.g. (on Amiga) diskperf ram:
**
** On the Amiga, you will need at least 256K bytes of "disk" wherever you
** choose to run. Unix systems will need about 3 mBytes free (larger size
** test files to delete buffer caching effect).
**
** Disclaimer:
**
** This benchmark is provided only for the purpose of seeing how fast
** _your_ system runs the program. No claims are made on my part
** as to what conclusions may be drawn from the statistics gathered.
** Just consider this program the "Sieve of Eratosthenes" of disk
** benchmarks - haggle over the numbers with friends, etc, but
** don't base purchasing decisions solely on the numbers produced
** by this program.
**
** Addendum:
** Timings may also be reported in BIX where Rick is rspanbauer. This has
** been slightly modified by jdow@bix. It no longer leaves dangling locks.
** It now executes reads as large as 524288 bytes. It also makes more reads
** so that hard disk timings are more accurate. As such it may be a bit
** difficult to run on smaller Amigas or particularly slow disk drives.
** It also now compiles under Lattice C. (At least 4.1.)
** lc:lc -dLATTICE -b0 -Lm -r0 diskperf ==> This works even if not optimal.
**
** Timings:
** Various timings gathered thus far:
**
-----------------------------------------------------------------------------
Amiga A-2000/A2620 ~14mHZ 68020, Micropolis 1578 HardDisk with MicroBotics
HardFrame controller.
File create/delete: create 20 files/sec, delete 55 files/sec
Directory scan: 227 entries/sec
Seek/read test: 317 seek/reads per second
r/w speed: buf 512 bytes, rd 123604 byte/sec, wr 28519 byte/sec
r/w speed: buf 4096 bytes, rd 194781 byte/sec, wr 163840 byte/sec
r/w speed: buf 8192 bytes, rd 32939= byte/sec, wr 247695 byte/sec
r/w speed: buf 32768 bytes, rd 683853 byte/sec, wr 367921 byte/sec
r/w speed: buf 131072 bytes, rd 925214 byte/sec, wr 483958 byte/sec
r/w speed: buf 524288 bytes, rd 953250 byte/sec, wr 537731 byte/sec
-----------------------------------------------------------------------------
Amiga A-1000, ~7mHz 68000, RAM:
File create/delete: create 5 files/sec, delete 10 files/sec
Directory scan: 5 entries/sec
Seek/read test: 51 seek/reads per second
r/w speed: buf 512 bytes, rd 201469 byte/sec, wr 154202 byte/sec
r/w speed: buf 4096 bytes, rd 655360 byte/sec, wr 374491 byte/sec
r/w speed: buf 8192 bytes, rd 873813 byte/sec, wr 374491 byte/sec
r/w speed: buf 32768 bytes, rd 873813 byte/sec, wr 436906 byte/sec
-----------------------------------------------------------------------------
Amiga A-1000, ~7mHz 68000, DF1:
File create/delete: create [0..1] files/sec, delete 1 files/sec
Directory scan: 43 entries/sec
Seek/read test: 18 seek/reads per second
r/w speed: buf 512 bytes, rd 11861 byte/sec, wr 5050 byte/sec
r/w speed: buf 4096 bytes, rd 12542 byte/sec, wr 5180 byte/sec
r/w speed: buf 8192 bytes, rd 12542 byte/sec, wr 5130 byte/sec
r/w speed: buf 32768 bytes, rd 12542 byte/sec, wr 5160 byte/sec
-----------------------------------------------------------------------------
Amiga A-1000/CSA Turbo board, ~14 mHz 68020, no 32 bit ram installed, RAM:
File create/delete: create 7 files/sec, delete 15 files/sec
Directory scan: 8 entries/sec
Seek/read test: 84 seek/reads per second
r/w speed: buf 512 bytes, rd 187245 byte/sec, wr 145625 byte/sec
r/w speed: buf 4096 bytes, rd 655360 byte/sec, wr 327680 byte/sec
r/w speed: buf 8192 bytes, rd 873813 byte/sec, wr 374491 byte/sec
r/w speed: buf 32768 bytes, rd 873813 byte/sec, wr 436906 byte/sec
-----------------------------------------------------------------------------
Amiga A-1000, ~7 mHz 68000, Ameristar NFS -> SUN-3/50, Micropolis 1325 disk:
File create/delete: create 3 files/sec, delete 7 files/sec
Directory scan: 10 entries/sec
Seek/read test: 35 seek/reads per second
r/w speed: buf 512 bytes, rd 30481 byte/sec, wr 3481 byte/sec
r/w speed: buf 4096 bytes, rd 113975 byte/sec, wr 21664 byte/sec
r/w speed: buf 8192 bytes, rd 145635 byte/sec, wr 38550 byte/sec
r/w speed: buf 32768 bytes, rd 145365 byte/sec, wr 37449 byte/sec
-----------------------------------------------------------------------------
SUN-3/50, Adaptec SCSI<->ST-506, Micropolis 1325 drive (5.25", 5 mBit/sec):
File create/delete: create 6 files/sec, delete 11 files/sec
Directory scan: 350 entries/sec
Seek/read test: 298 seek/reads per second
r/w speed: buf 512 bytes, rd 240499 byte/sec, wr 215166 byte/sec
r/w speed: buf 4096 bytes, rd 234057 byte/sec, wr 182466 byte/sec
r/w speed: buf 8192 bytes, rd 233189 byte/sec, wr 179755 byte/sec
r/w speed: buf 32768 bytes, rd 236343 byte/sec, wr 187580 byte/sec
-----------------------------------------------------------------------------
**
** Some sample figures from "large" systems:
**
-----------------------------------------------------------------------------
SUN-3/160, Fujitsu SuperEagle, Interphase VSMD-3200 controller:
File create/delete: create 15 files/sec, delete 18 files/sec
Directory scan: 722 entries/sec
Seek/read test: 465 seek/reads per second
r/w speed: buf 512 bytes, rd 361162 byte/sec, wr 307200 byte/sec
r/w speed: buf 4096 bytes, rd 419430 byte/sec, wr 315519 byte/sec
r/w speed: buf 8192 bytes, rd 409067 byte/sec, wr 314887 byte/sec
r/w speed: buf 32768 bytes, rd 409600 byte/sec, wr 328021 byte/sec
-----------------------------------------------------------------------------
SUN-3/75, NFS filesystem, full 8192 byte transactions:
File create/delete: create 9 files/sec, delete 12 files/sec
Directory scan: 88 entries/sec
Seek/read test: 282 seek/reads per second
r/w speed: buf 512 bytes, rd 238674 byte/sec, wr 52012 byte/sec
r/w speed: buf 4096 bytes, rd 259334 byte/sec, wr 54956 byte/sec
r/w speed: buf 8192 bytes, rd 228116 byte/sec, wr 26483 byte/sec
r/w speed: buf 32768 bytes, rd 243477 byte/sec, wr 36174 byte/sec
-----------------------------------------------------------------------------
DEC VAX 780, RP07:
File create/delete: create 12 files/sec, delete 12 files/sec
Directory scan: 509 entries/sec
Seek/read test: 245 seek/reads per second
r/w speed: buf 512 bytes, rd 168041 byte/sec, wr 141064 byte/sec
r/w speed: buf 4096 bytes, rd 210135 byte/sec, wr 239765 byte/sec
r/w speed: buf 8192 bytes, rd 206277 byte/sec, wr 239948 byte/sec
r/w speed: buf 32768 bytes, rd 199222 byte/sec, wr 232328 byte/sec
-----------------------------------------------------------------------------
DEC VAX 750, RA81:
File create/delete: create 12 files/sec, delete 15 files/sec
Directory scan: 208 entries/sec
Seek/read test: 153 seek/reads per second
r/w speed: buf 512 bytes, rd 99864 byte/sec, wr 72549 byte/sec
r/w speed: buf 4096 bytes, rd 142663 byte/sec, wr 166882 byte/sec
r/w speed: buf 8192 bytes, rd 147340 byte/sec, wr 153525 byte/sec
r/w speed: buf 32768 bytes, rd 142340 byte/sec, wr 141571 byte/sec
-----------------------------------------------------------------------------
*/
#ifdef UNIX
#include <sys/types.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/stat.h>
#define SCAN_ITER 10
#define RW_ITER 3
#define RW_SIZE (3*1024*1024)
#define SEEK_TEST_FSIZE (1024*1024)
#define OPEN_TEST_FILES 200
#define TIMER_RATE 100
/*
** Amiga compatibility library for Unix. These are NOT full or correct
** emulations of the Amiga I/F routines - they are intended only to
** run this benchmark.
*/
#define MODE_OLDFILE 1005
#define MODE_NEWFILE 1006
#define ERROR_NO_MORE_ENTRIES
#define OFFSET_BEGINNING -1
#define OFFSET_CURRENT 0
int
Open(name, accessMode)
char *name;
long accessMode;
{
int flags, file;
flags = O_RDWR;
if(accessMode == MODE_NEWFILE)
flags |= O_TRUNC|O_CREAT;
if((file = open(name, flags, 0644)) < 0)
file = 0;
return(file);
}
/*
** To be fair, write should be followed by fsync(file) to flush cache. But
** since when are benchmarks fair??
*/
#define Write(file, buffer, length) write(file, buffer, length)
#define Read(file, buffer, length) read(file, buffer, length)
#define Close(file) close(file)
#define CreateDir(name) mkdir(name, 0755)
#define Seek(file, position, mode) lseek(file, position, \
(mode==OFFSET_BEGINNING ? 0 : (mode==OFFSET_CURRENT?1:2)))
#define AllocMem(size, constraints) malloc(size)
#define FreeMem(p, size) free(p, size)
#define DeleteFile(filename) unlink(filename)
int
timer_init()
{
return(1);
}
void
timer_quit()
{
}
void
timer(valp)
long *valp;
{
static struct timeval ref;
struct timeval current;
if(valp == (long *)0){
gettimeofday(&ref, 0);
return;
}
gettimeofday(¤t, 0);
*valp = (current.tv_usec - ref.tv_usec)/(1000000/TIMER_RATE);
if(*valp < 0){
current.tv_sec--;
*valp += TIMER_RATE;
}
*valp += (current.tv_sec - ref.tv_sec)*TIMER_RATE;
}
int
OpenStat(filename)
char *filename;
{
int fd, result;
struct stat statb;
if((fd = open(filename, 0)) < 0)
return(0);
result = fstat(fd, &statb);
close(fd);
return(result == 0);
}
#else
/*
** Iteration/size definitions smaller for Amiga so benchmark doesn't take
** as long and fits on empty floppy.
*/
#include <exec/types.h>
#include <libraries/dos.h>
#include <devices/timer.h>
#ifdef MANX
#include <functions.h> /* For Manx only */
#endif
#define SCAN_ITER 5
#define RW_ITER 3
#define RW_SIZE (2*1024*1024)
#define SEEK_TEST_FSIZE (256*1024)
#define OPEN_TEST_FILES 100
#define TIMER_RATE 10 /* misnomer, should be resolution */
struct MsgPort *timerport, *CreatePort();
struct timerequest *timermsg, *CreateExtIO();
long TimerBase;
int
timer_init()
{
timerport = CreatePort(0, 0);
if(timerport == (struct MsgPort *)0)
return(0);
timermsg = CreateExtIO(timerport, sizeof(struct timerequest));
if(timermsg == (struct timerequest *)0){
DeletePort(timerport);
return(0);
}
if(OpenDevice(TIMERNAME, UNIT_VBLANK, timermsg, 0) != 0){
DeletePort(timerport);
DeleteExtIO(timermsg, sizeof(struct timerequest));
return(0);
}
TimerBase = (long)timermsg->tr_node.io_Device; /* Hack */
return(1);
}
void
timer_quit()
{
CloseDevice(timermsg);
DeleteExtIO(timermsg, sizeof(struct timerequest));
DeletePort(timerport);
}
void
timer(valp)
long *valp;
{
static struct timeval ref;
long t;
timermsg->tr_node.io_Command = TR_GETSYSTIME;
DoIO(timermsg);
t = timermsg->tr_time.tv_secs;
if(valp == (long *)0)
ref = timermsg->tr_time;
else {
SubTime(&timermsg->tr_time, &ref);
*valp = timermsg->tr_time.tv_secs*TIMER_RATE +
(timermsg->tr_time.tv_micro/(1000000/TIMER_RATE));
}
}
int
OpenStat(filename)
char *filename;
{
long lock, result;
static struct FileInfoBlock fib; /* must be on &fib mod 4 == 0 */
if((lock = Lock(filename, MODE_OLDFILE)) == 0)
return(0);
result = Examine(lock, &fib);
UnLock(lock);
return(result);
}
#endif
/*
** Benchmarks performed:
**
** 1) Raw file read/write rates. Tested for operation sizes of
** 512/4096/8192/32768/131072/524288 bytes. Return read/write figures
** for each tranfer size in bytes/sec.
**
** 2) Directory create/delete rates. Return create/delete entries
** per second.
**
** 3) Directory lookup rate. Create files in directory, and
** then measure time to lookup, open & stat entire directory contents.
** Return entries/second.
**
** 4) Seek speed test - create large file, then seek to various
** positions in file & read one byte. Seek distances intentionally
** chosen large to reduce cacheing effectiveness - want basic
** speed of disk format here. Return seeks/second.
*/
char *prepend = ""; /* prepend this path to all filenames created */
char scratch[8192]; /* scratch buffer used in various tests */
/*
** Our `C' library for the Amiga is a bit different than Unix's, so this
** routine will look a bit obtuse to most of you. Trying to avoid using
** sprintf()..
*/
void
maketemp(buf, pref)
char *buf;
{
char *p, *q;
int fnum;
static int cnt;
fnum = cnt++;
q = buf;
if(pref)
for(p = prepend; *p; )
*q++ = *p++;
for(p = "diskperf"; *p; )
*q++ = *p++;
*q++ = 'A' + ((fnum>>8)&0xf);
*q++ = 'A' + ((fnum>>4)&0xf);
*q++ = 'A' + (fnum&0xf);
*q++ = 0;
}
long sptest[] = {512, 4096, 8192, 32768, 131072, 524288, 0};
void rw_test()
{
long i, j, k, maxsize, file, RDaccTime, WRaccTime, Dt, error;
char *p, filename[64];
maxsize = -1;
for(k = 0; sptest[k] != 0; k++)
if(sptest[k] > maxsize)
maxsize = sptest[k];
if((p = (char *)AllocMem(maxsize, 0)) == (char *)0L){
printf("Could not get %d bytes of memory\n", maxsize);
return;
}
for(k = 0; sptest[k] != (char *) 0L; k++){
RDaccTime = WRaccTime = 0;
for(j = 0; j < RW_ITER; j++){
maketemp(filename, 1);
if((file = (long) Open(filename, MODE_NEWFILE)) == 0){
printf("Could not create %s\n", filename);
return;
}
timer(0);
for(i = RW_SIZE/sptest[k]; i > 0; i--)
error = Write(file, p, sptest[k]);
timer(&Dt);
if (error != sptest[k])
printf("Write error! %d != %d\n", sptest[k], error);
WRaccTime += Dt;
Close(file);
if((file = (long) Open(filename, MODE_OLDFILE)) == 0){
printf("Could not open %s\n", filename);
return;
}
timer(0);
for(i = RW_SIZE/sptest[k]; i > 0; i--)
error = Read(file, p, sptest[k]);
timer(&Dt);
if (error != sptest[k])
printf("Read error! %d != %d\n", sptest[k], error);
RDaccTime += Dt;
Close(file);
DeleteFile(filename);
}
if (RDaccTime == 0) printf( "Still bingo read.\n");
else printf("r/w speed:\t buf %d bytes, rd %d byte/sec, wr %d byte/sec\n",
sptest[k],
(TIMER_RATE*RW_SIZE*RW_ITER)/RDaccTime,
(TIMER_RATE*RW_SIZE*RW_ITER)/WRaccTime);
}
FreeMem(p, maxsize);
}
void
seek_test()
{
char fname[64];
long i, fd, Dt, cnt, pos, dist;
maketemp(fname, 1);
if((fd = (long) Open(fname, MODE_NEWFILE)) == 0){
printf("Could not create %s\n", fname);
return;
}
for(i = SEEK_TEST_FSIZE/sizeof(scratch); i > 0; i--)
if(Write(fd, scratch, sizeof(scratch)) != sizeof(scratch))
break;
if(i == 0){
cnt = 0;
timer(0);
for(dist = 256; dist <= 65536; dist <<= 2)
for(pos = 0; pos < SEEK_TEST_FSIZE; pos += dist){
cnt++;
Seek(fd, pos, OFFSET_BEGINNING);
Read(fd, scratch, 1);
}
timer(&Dt);
printf("Seek/read test:\t %d seek/reads per second\n",
(TIMER_RATE*cnt)/Dt);
}
Close(fd);
DeleteFile(fname);
}
char tempname[OPEN_TEST_FILES][16];
void
open_scan_test()
{
char dirname[64];
long lock, oldlock, cDt, dDt, sDt, i, j, fd, numRead;
/* struct FileInfoBlock *fib; */
maketemp(dirname, 1);
lock = CreateDir(dirname);
#ifdef UNIX
chdir(dirname);
#else
oldlock = CurrentDir(lock);
#endif
for(i = 0; i < OPEN_TEST_FILES; i++)
maketemp(tempname[i], 0);
/*
** Time Open of files.
*/
timer(0);
for(i = 0; i < OPEN_TEST_FILES; i++){
if((fd = Open(tempname[i], MODE_NEWFILE)) == 0){
printf("Could not open %s/%s\n", dirname, tempname);
break;
}
Close(fd);
}
timer(&cDt);
/*
** Time open scan of directory.
*/
timer(0);
numRead = 1;
for(i = 0; i < SCAN_ITER; i++)
for(j = 0; j < OPEN_TEST_FILES; j++)
if(OpenStat(tempname[i]) != 0)
numRead++;
timer(&sDt);
/*
** Time Close of files.
*/
timer(0);
for(i = 0; i < OPEN_TEST_FILES; i++)
DeleteFile(tempname[i]);
timer(&dDt);
printf("File create/delete: create %d files/sec, delete %d files/sec\n",
(TIMER_RATE*OPEN_TEST_FILES)/cDt,
(TIMER_RATE*OPEN_TEST_FILES)/dDt);
printf("Directory scan:\t %d entries/sec\n",
(TIMER_RATE*numRead)/sDt);
#ifdef UNIX
chdir("..");
rmdir(dirname);
#else
CurrentDir(oldlock);
UnLock(lock);
DeleteFile(dirname);
#endif
}
void
main(argc, argv)
int argc;
char **argv;
{
if(!timer_init()){
printf("Could not init timer\n");
return(0); /* Exit in most systems, but not ours! */
}
if(argc > 1)
prepend = argv[1];
open_scan_test();
seek_test();
rw_test();
}